using System;
using org.in2bits.MyXls;

namespace MySpreadsheet
{
    public class MyXlsRenderer
    {
        private const double ColumnWidthScaleFactor = 256;
        private const double FontScaleFactor = 20;

        public XlsDocument Render(WorkBook workbook)
        {
            var xls = new XlsDocument();
            xls.FileName = workbook.Name;

            foreach (var sheet in workbook.WorkSheets)
            {
                AddWorkSheetToDocument(xls, sheet);
            }

            return xls;
        }

        public void Write(WorkBook workBook)
        {
            var xls = Render(workBook);
            xls.Save(true);
        }

        private void AddWorkSheetToDocument(XlsDocument xls, WorkSheet sheet)
        {
            var xlsSheet = xls.Workbook.Worksheets.Add(sheet.Name);

            var rowIndex = 1;
            foreach (var row in sheet.Rows)
            {
                var columnIndex = 1;
                foreach (var cell in row.Cells)
                {
                    Console.WriteLine(cell.Value);
                    var xlsCell = xlsSheet.Cells.Add(rowIndex, columnIndex, cell.Value);

                    ApplyCellFormat(cell, xlsCell);

                    columnIndex++;
                }
                rowIndex++;
            }

            FormatColumns(xls, xlsSheet, sheet);
        }

        private void FormatColumns(XlsDocument xls, Worksheet xlsSheet, WorkSheet sheet)
        {
            foreach (var column in sheet.Columns)
            {
                var columnInfo = new org.in2bits.MyXls.ColumnInfo(xls, xlsSheet);
                columnInfo.ColumnIndexStart = (ushort) (column.StartIndex - 1);
                columnInfo.ColumnIndexEnd = (ushort) (column.EndIndex - 1);
                columnInfo.Width = (ushort) (column.Width * ColumnWidthScaleFactor);
                xlsSheet.AddColumnInfo(columnInfo);
            }
        }

        private void ApplyCellFormat(Cell sourceCell, org.in2bits.MyXls.Cell destinationCell)
        {
            destinationCell.Font.Height = (ushort) (sourceCell.Font.Size * FontScaleFactor);
            destinationCell.Font.Bold = sourceCell.Font.Bold;

            destinationCell.Rotation = (short)sourceCell.Format.Rotation;

            SetBorder(destinationCell, sourceCell.Format.Border);
        }

        private void SetBorder(org.in2bits.MyXls.Cell cell, Border border)
        {
            cell.TopLineStyle = (ushort)Convert(border.Top);
            cell.BottomLineStyle = (ushort)Convert(border.Bottom);
            cell.LeftLineStyle = (ushort)Convert(border.Left);
            cell.RightLineStyle = (ushort)Convert(border.Right);
        }

        public org.in2bits.MyXls.LineStyle Convert(LineStyle lineStyle)
        {
            switch (lineStyle)
            {
                case LineStyle.None:
                    return org.in2bits.MyXls.LineStyle.None;
                case LineStyle.Thick:
                    return org.in2bits.MyXls.LineStyle.Thick;
                case LineStyle.Thin:
                    return org.in2bits.MyXls.LineStyle.Thin;
                default:
                    throw new ArgumentException("Cannot convert this linestyle.");
            }
        }
    }
}